package com.oig.sys.base.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.oig.common.constants.CommonEnum;
import com.oig.common.exception.BadRequestException;
import com.oig.common.module.SysPageInfo;
import com.oig.common.module.SysRequest;
import com.oig.sys.base.dao.ITbCountryGroupDao;
import com.oig.sys.base.dto.CountryGroupDto;
import com.oig.sys.base.entity.TbCountryGroup;
import com.oig.sys.base.service.ITbCountryGroupMemberService;
import com.oig.sys.base.service.ITbCountryGroupService;
import com.oig.sys.base.vo.CountryGroupMemberVo;
import com.oig.sys.base.vo.CountryGroupVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @author wuxl
 */
@Service
public class TbCountryGroupServiceImpl implements ITbCountryGroupService {

	private final ITbCountryGroupDao tbCountryGroupDao;
	private final ITbCountryGroupMemberService countryGroupMemberService;

	@Autowired
	public TbCountryGroupServiceImpl(ITbCountryGroupDao tbCountryGroupDao,
									 ITbCountryGroupMemberService countryGroupMemberService){
		 this.tbCountryGroupDao = tbCountryGroupDao;
		 this.countryGroupMemberService = countryGroupMemberService;
	}

	@Transactional
	@Override
	public CountryGroupVo addCountryGroup(CountryGroupDto countryGroupDto) {
		TbCountryGroup countryGroup = new TbCountryGroup();
		countryGroup.setName(countryGroupDto.getName());
		countryGroup.setDescInfo(countryGroupDto.getDescInfo());
		countryGroup.setStatus(CommonEnum.CommonStatusEnum.OK.getCode());
		this.tbCountryGroupDao.save(countryGroup);
		List<CountryGroupMemberVo> countryVos= null;
		if (countryGroupDto.getCountryList()!=null){
			countryVos = this.countryGroupMemberService.addGroupMembers(countryGroup.getId(),countryGroupDto.getCountryList());
		}
		CountryGroupVo countryGroupVo = new CountryGroupVo();
		BeanUtils.copyProperties(countryGroup,countryGroupVo);
		countryGroupVo.setCountryList(countryVos);
		return countryGroupVo;
	}

	@Transactional
	@Override
	public CountryGroupVo updateCountryGroup(CountryGroupDto countryGroupDto) {
		TbCountryGroup countryGroup = this.tbCountryGroupDao.getTbCountryGroupById(countryGroupDto.getId()) ;
		if (countryGroup==null){
			throw new BadRequestException("error id") ;
		}
		BeanUtils.copyProperties(countryGroupDto, countryGroup, "id");
		this.tbCountryGroupDao.save(countryGroup);
		CountryGroupVo countryGroupVo = new CountryGroupVo();
		BeanUtils.copyProperties(countryGroup,countryGroupVo);
		if (countryGroupDto.getCountryList()!=null){
			countryGroupVo.setCountryList(this.countryGroupMemberService.updateGroupMembers(countryGroup.getId(),countryGroupDto.getCountryList()));
		}
		return countryGroupVo;
	}

	@Transactional
	@Override
	public void cancelCountryGroup(Integer id) {
		TbCountryGroup countryGroup = this.tbCountryGroupDao.getTbCountryGroupById(id);
		countryGroup.setStatus(CommonEnum.CommonStatusEnum.DEL.getCode());
		this.tbCountryGroupDao.save(countryGroup);
	}

	@Override
	public CountryGroupVo getCountryGroup(Integer id) {
		TbCountryGroup countryGroup = this.tbCountryGroupDao.getTbCountryGroupById(id);
		if (countryGroup==null){
			throw new BadRequestException("error id") ;
		}
		List<CountryGroupMemberVo> countryVoList =  countryGroupMemberService.findGroupAllMember(id) ;
		CountryGroupVo vo = new CountryGroupVo();
		BeanUtils.copyProperties(countryGroup,vo);
		vo.setCountryList(countryVoList);
		return vo;
	}

	@Override
	public SysPageInfo<CountryGroupVo> findCountryGroup(SysRequest<CountryGroupDto> countryGroupRequest) {
		Pageable pageable = countryGroupRequest.pageable();
		Page<TbCountryGroup> countryGroupPage ;
		if (countryGroupRequest.getParamDto()!=null){
			Specification<TbCountryGroup> specification = new Specification<TbCountryGroup>() {
				@Override
				@Nullable
				public Predicate toPredicate(@NonNull Root<TbCountryGroup> root, @NonNull CriteriaQuery<?> criteriaQuery, @NonNull CriteriaBuilder criteriaBuilder) {
					List<Predicate> predicateList = new ArrayList<>();
					if (!ObjectUtil.isEmpty(countryGroupRequest.getParamDto().getId())) {
						Path<String> idPath = root.get("id");
						predicateList.add(criteriaBuilder.equal(idPath, countryGroupRequest.getParamDto().getId()));
					}
					if (StrUtil.isNotBlank(countryGroupRequest.getParamDto().getName())) {
						Path<String> namePath = root.get("name");
						predicateList.add(criteriaBuilder.like(namePath, "%" + countryGroupRequest.getParamDto().getName() + "%"));
					}
					if (StrUtil.isNotBlank(countryGroupRequest.getParamDto().getDescInfo())) {
						Path<String> descInfoPath = root.get("descInfo");
						predicateList.add(criteriaBuilder.like(descInfoPath, "%" + countryGroupRequest.getParamDto().getDescInfo() + "%"));
					}
					criteriaQuery.where(predicateList.toArray(new Predicate[0]));
					return criteriaQuery.getRestriction();
				}
			} ;
			countryGroupPage = this.tbCountryGroupDao.findAll(specification,pageable);
		} else {
			countryGroupPage = this.tbCountryGroupDao.findAll(pageable);
		}
		List<CountryGroupVo> countryGroupVoList = new ArrayList<>();
		for (TbCountryGroup countryGroup : countryGroupPage.getContent()){
			countryGroupVoList.add(this.buildVo(countryGroup));
		}
		SysPageInfo<CountryGroupVo> sysPageInfo = new SysPageInfo<>(countryGroupRequest.getPageNo(), countryGroupRequest.getPageSize(), countryGroupPage.getTotalElements());
		sysPageInfo.setList(countryGroupVoList);
		return sysPageInfo;
	}

	private CountryGroupVo buildVo(TbCountryGroup countryGroup){
		CountryGroupVo countryGroupVo = new CountryGroupVo();
		BeanUtils.copyProperties(countryGroup, countryGroupVo);
		return countryGroupVo;
	}

	@Override
	public List<CountryGroupVo> findAllCountryGroup() {
		List<CountryGroupVo> countryGroupVoList = new ArrayList<>();
		List<TbCountryGroup> groupList = this.tbCountryGroupDao.findByOkGroup();
		if (groupList!=null && !groupList.isEmpty()){
			for (TbCountryGroup countryGroup : groupList){
				CountryGroupVo countryGroupVo = this.buildVo(countryGroup);
				countryGroupVo.setCountryList(countryGroupMemberService.findGroupAllMember(countryGroup.getId()));
				countryGroupVoList.add(countryGroupVo);
			}
		}
		return countryGroupVoList;
	}

	@Override
	public CountryGroupVo findGroupAllByName(String name) {
		TbCountryGroup countryGroup = this.tbCountryGroupDao.getTbCountryGroupByName(name);
		if (countryGroup==null) return null;
		CountryGroupVo countryGroupVo = this.buildVo(countryGroup);
		countryGroupVo.setCountryList(countryGroupMemberService.findGroupAllMember(countryGroup.getId()));
		return countryGroupVo;
	}

}
